home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / aie9009.zip / FRAMES.ZIP / NEWFRAME.ARI < prev    next >
Text File  |  1990-07-09  |  17KB  |  693 lines

  1.  
  2. %                 FRAME LIBRARY
  3. %
  4. %                    by
  5. %
  6. %                 Instant Recall
  7. %                 P.O. Box 30134
  8. %                 Bethesda, Md. 20814
  9. %                 (301) 530-0898
  10. %                 BBS: (301) 530-2890
  11. %
  12. %                 (C) Copyright 1990 by Instant Recall
  13. %                 All Rights Reserved
  14. :- module  newframe.
  15. :- segment(libseg).
  16.  
  17. /*
  18. * get slot value
  19. * get slot value with default
  20. * get slot values
  21. * has slot
  22. * index frame into database
  23. * learn indexed frame update
  24. * retrieve frame from database
  25. * retrieve indexed frame
  26. * retrieve or create indexed frame
  27. satisfies pattern,
  28. types match$,
  29. */
  30.  
  31. :- public frame_op / 2 : far .
  32. :- public frame_op / 3 : far .
  33. :- public frame_op / 4 : far .
  34. :- public frame_op / 5 : far .
  35. :- public frame_op / 6 : far .
  36. :- visible frame_op / 2       .
  37. :- visible frame_op / 3       .
  38. :- visible frame_op / 4       .
  39. :- visible frame_op / 5       .
  40. :- visible frame_op / 6       .
  41. :- extrn append / 3 : far .
  42. :- extrn trace_message / 3 : far .
  43. :- extrn frame_op      / 0 : interp .
  44.  
  45. %%%%%%%%%%%%%%%%% IMPLEMENTATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  46.  
  47.  
  48. %%%%%%%%%%%%%%%%% frame_op / 2    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  49. %%%%%%%%%%%%%%%%% frame_op / 2    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  50.  
  51. :- mode frame_op( +,+).
  52.  
  53. frame_op( KEY,
  54.           FRAME2  ) :-
  55.      ARGS =  FRAME2  ,
  56.      frame_op( $trace$,
  57.                KEY,
  58.                ARGS ) ,
  59.      fail.
  60.  
  61. frame_op( $purge database$,
  62.           PATTERN ) :-
  63.      frame_op( $retrieve frame from database$,
  64.                PATTERN,
  65.                RETRIEVED_FRAME ) ,
  66.      retract( RETRIEVED_FRAME ),
  67.      fail.
  68. frame_op( $purge database$,
  69.           _       ) :-!.
  70.  
  71. %%%%%%%%%%%%%%%%% frame_op / 3    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  72. %%%%%%%%%%%%%%%%% frame_op / 3    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  73.  
  74. :- mode frame_op( +,+,?).
  75.  
  76. % cl 0
  77.  
  78. frame_op( $trace$,
  79.           KEY,
  80.           ARGS ) :-
  81.   !,
  82.   (   call( frame_op ),
  83.       !,
  84.       concat( [$e $, KEY , $ args = $], MSG ),
  85.       trace_message( frame_op,
  86.                      MSG,
  87.                      ARGS)
  88.   ;
  89.       true
  90.   ).
  91.  
  92. frame_op( $x trace$,
  93.           KEY,
  94.           ARG  ) :-
  95.   !,
  96.   (   call( frame_op ),
  97.       !,
  98.       concat( [$x $, KEY , $ RESULT = $], MSG ),
  99.       trace_message( frame_op,
  100.                      MSG,
  101.                      ARG)
  102.   ;
  103.       true
  104.   ).
  105.  
  106. frame_op( KEY,
  107.           FRAME1 ,
  108.           FRAME2  ) :-
  109.      ARGS = [ FRAME1, FRAME2 ],
  110.      frame_op( $trace$,
  111.                KEY,
  112.                ARGS ) ,
  113.      fail.
  114.  
  115.  
  116. frame_op( $learn prolog database frame update$,
  117.           PATTERN,
  118.           NEW_FRAME ) :-
  119.     frame_op( $purge database$,
  120.               PATTERN ) ,
  121.     asserta( NEW_FRAME ) .
  122.  
  123. % cl 1
  124. frame_op( $types match$,
  125.           FRAME1 ,
  126.           FRAME2  ) :-
  127.       frame_op( $frame info$,
  128.                 FRAME1  ,
  129.                 FUNCTOR1,
  130.                 _     ) ,
  131.       frame_op( $frame info$,
  132.                 FRAME2  ,
  133.                 FUNCTOR2,
  134.                 _     ) ,
  135.       frame_op( $unify types$,
  136.                 FUNCTOR1,
  137.                 FUNCTOR2,
  138.                 _  ),
  139.       frame_op( $x trace$,
  140.                 $types match$,
  141.                 true ) .
  142.  
  143.  
  144.  
  145. % cl 2
  146. frame_op( $satisfies pattern$,
  147.           FRAME,
  148.           PATTERN ) :-
  149.      frame_op( $types match$,
  150.                FRAME,
  151.                PATTERN ) ,
  152.      frame_op( $get slot values$,
  153.                FRAME,
  154.                PATTERN ,
  155.                _ ) ,
  156.       frame_op( $x trace$,
  157.                 $satisfies pattern$,
  158.                 true ) .
  159.  
  160.  
  161. % cl 3
  162. frame_op( $retrieve frame from database$,
  163.           PATTERN,
  164.           RETRIEVED_FRAME ) :-
  165.        PATTERN =.. [ FUNCTOR , SLOTS ] ,
  166.        RETRIEVED_FRAME =.. [ FUNCTOR, _  ],
  167.        call( RETRIEVED_FRAME ),
  168.        frame_op( $get slot values$,
  169.                  RETRIEVED_FRAME ,
  170.                  SLOTS ),
  171.       frame_op( $x trace$,
  172.                 $retrieve frame from database$,
  173.                 RETRIEVED_FRAME  ) .
  174.  
  175. % cl 4
  176. frame_op( $index frame into database$,
  177.           KEY,
  178.           FRAME ) :-
  179.       recordz( KEY, FRAME , _ ) ,
  180.       frame_op( $x trace$,
  181.                 $index frame into database$,
  182.                 FRAME  ) .
  183.  
  184. % cl 5
  185. frame_op( $has slot$,
  186.           FRAME,
  187.           SLOT ) :-
  188.       frame_op( $get slot value$,
  189.                 FRAME,
  190.                 SLOT,
  191.                 _  ) ,
  192.       frame_op( $x trace$,
  193.                 $has slot$,
  194.                 true   ) .
  195.  
  196.  
  197.         % this less elabaorate form can not have the
  198.         % optional and unacceptable modifiers in the
  199.         % SLOTS TO GET
  200. % cl 7
  201. frame_op( $get slot values$,
  202.           _ , % SOURCE_FRAME,
  203.           []  ):- !,
  204.    frame_op( $x trace$,
  205.              $get slot values$,
  206.              []   ) .
  207.  
  208. frame_op( $get slot values$,
  209.           SOURCE_FRAME,
  210.           OUTPUT       ):-
  211.     OUTPUT =  [S : V | R ] ,
  212.     frame_op( $get slot value$,
  213.               SOURCE_FRAME,
  214.               S,
  215.               V),
  216.     frame_op( $get slot values$,
  217.               SOURCE_FRAME,
  218.               R  ) ,
  219.    frame_op( $x trace$,
  220.              $get slot values$,
  221.              OUTPUT   ) .
  222.  
  223.  
  224. % cl 8
  225. frame_op( $get pair slot$,
  226.           PAIR ,
  227.           SLOT   )         :-
  228.        PAIR = SLOT : _ ,
  229.    frame_op( $x trace$,
  230.              $get pair slot$,
  231.              SLOT     ) .
  232.  
  233. %%%%%%%%%%%%%%%%% frame_op / 4    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  234. %%%%%%%%%%%%%%%%% frame_op / 4    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  235.  
  236.  
  237. :- mode frame_op( +,+,+,?).
  238.  
  239.  
  240. %%%%%%%%%%%%%%%%%%% retrieve or create indexed frame %%%%%%%%%%%%
  241.  
  242.  
  243. frame_op( KEY,
  244.           FRAME1 ,
  245.           FRAME1a ,
  246.           FRAME2  ) :-
  247.      ARGS = [ FRAME1, FRAME1a, FRAME2  ],
  248.      frame_op( $trace$,
  249.                KEY,
  250.                ARGS ) ,
  251.      fail.
  252.  
  253. % cl 1
  254. frame_op( $retrieve or create indexed frame$,
  255.           KEY ,
  256.           PATTERN  ,
  257.           FRAME ) :-
  258.      frame_op( $retrieve indexed frame$,
  259.                KEY ,
  260.                PATTERN  ,
  261.                FRAME ) ,
  262.      !,
  263.    frame_op( $x trace$,
  264.              $retrieve or create indexed frame$,
  265.              FRAME  ) .
  266.  
  267. % cl 2
  268. frame_op( $retrieve or create indexed frame$,
  269.           KEY ,
  270.           PATTERN  ,
  271.           PATTERN ) :-
  272.      recorda( KEY, PATTERN , _ ),
  273.    frame_op( $x trace$,
  274.              $retrieve or create indexed frame$,
  275.              PATTERN    ) .
  276.  
  277.  
  278. % cl 3
  279. frame_op( $retrieve indexed frame$,
  280.           KEY ,
  281.           PATTERN  ,
  282.           RETRIEVED_FRAME ) :-
  283.        PATTERN =.. [ FUNCTOR , SLOTS ] ,
  284.        RETRIEVED_FRAME =.. [ FUNCTOR, _ ],
  285.        recorded( KEY, RETRIEVED_FRAME, _ ),
  286.        frame_op( $get slot values$,
  287.                  RETRIEVED_FRAME ,
  288.                  SLOTS ),
  289.    frame_op( $x trace$,
  290.              $retrieve indexed frame$,
  291.              RETRIEVED_FRAME    ) .
  292.  
  293. % cl 4
  294. frame_op( $frame info$,
  295.           FRAME   ,
  296.           FUNCTOR ,
  297.           SLOTS ) :-
  298.      (   (  FRAME = [ _ | _ ]
  299.          ;
  300.             FRAME = []
  301.          ),
  302.          !,
  303.          SLOTS = FRAME,
  304.          FUNCTOR = untyped
  305.      ;
  306.          FRAME =.. [ FUNCTOR , SLOTS ]
  307.      ),
  308.      !,
  309.    frame_op( $x trace$,
  310.              $frame info$,
  311.              SLOTS  ) .
  312.  
  313. %%%%%%%%%%%%%%%%%%% get slot value %%%%%%%%%%%%%%%%%%%
  314.  
  315. % cl 5
  316. frame_op( $get slot value$,
  317.           [ SLOT : VALUE | _   ],
  318.           SLOT,
  319.           VALUE ) :- !,
  320.    frame_op( $x trace$,
  321.              $get slot value$,
  322.              VALUE  ) .
  323.  
  324. % cl 6
  325. frame_op( $get slot value$,
  326.           [ _ | REST  ],
  327.           SLOT,
  328.           VALUE ) :-
  329.       !,
  330.       frame_op( $get slot value$,
  331.                 REST  ,
  332.                 SLOT,
  333.                 VALUE ) ,
  334.    frame_op( $x trace$,
  335.              $get slot value$,
  336.              VALUE  ) .
  337.  
  338. % cl 7
  339. frame_op( $get slot value$,
  340.           TERM ,
  341.           SLOT,
  342.           VALUE ) :-
  343.       TERM =..[ _ , SLOTS ],
  344.       !,
  345.       frame_op( $get slot value$,
  346.                 SLOTS  ,
  347.                 SLOT,
  348.                 VALUE ) ,
  349.    frame_op( $x trace$,
  350.              $get slot value$,
  351.              VALUE  ) .
  352.  
  353. %%%%%%%%%%%%%%%%%%% get slot values %%%%%%%%%%%%%%%%%%%
  354.  
  355.  
  356. frame_op( $get slot values$,
  357.           SOURCE_FRAME,
  358.           SLOTS_TO_GET,
  359.           RESULTING_SLOT_LIST ) :-
  360.      var( SLOTS_TO_GET ),
  361.      !,
  362.      frame_op( $frame info$,
  363.                SOURCE_FRAME,
  364.                _,
  365.                RESULTING_SLOT_LIST ),
  366.    frame_op( $x trace$,
  367.              $get slot values$,
  368.              RESULTING_SLOT_LIST  ) .
  369.  
  370. % cl 8
  371. frame_op( $get slot values$,
  372.           _ , % SOURCE_FRAME,
  373.           SLOTS_TO_GET,
  374.           RESULTING_SLOT_LIST ) :-
  375.      SLOTS_TO_GET = [],
  376.      !,
  377.      RESULTING_SLOT_LIST  = [],
  378.    frame_op( $x trace$,
  379.              $get slot values$,
  380.              RESULTING_SLOT_LIST  ) .
  381.  
  382. % cl 9
  383. frame_op( $get slot values$,
  384.           SOURCE_FRAME,
  385.           SLOTS_TO_GET,
  386.           RESULTING_SLOT_LIST ) :-
  387.      SLOTS_TO_GET = [ PAIR | REST ],
  388.      frame_op( $get pair slot$,
  389.                PAIR ,
  390.                SLOT   ) ,
  391.      frame_op( $get pair value$,
  392.                SOURCE_FRAME,
  393.                SLOT ,
  394.                PAIR ,
  395.                VALUE  ) ,
  396.      RESULTING_SLOT_LIST = [ SLOT : VALUE | REST1 ],
  397.      frame_op( $get slot values$,
  398.                SOURCE_FRAME,
  399.                REST ,
  400.                REST1 ),
  401.    frame_op( $x trace$,
  402.              $get slot values$,
  403.              RESULTING_SLOT_LIST  ) .
  404.  
  405.  
  406. % cl 10
  407.  
  408.  
  409. % cl 11
  410. frame_op( $unify frames$,
  411.           FRAME1    ,
  412.           FRAME2    ,
  413.           NEW_FRAME ) :-
  414.       frame_op( $frame info$,
  415.                 FRAME1  ,
  416.                 FUNCTOR1,
  417.                 SLOTS1) ,
  418.       frame_op( $frame info$,
  419.                 FRAME2  ,
  420.                 FUNCTOR2,
  421.                 SLOTS2) ,
  422.       frame_op( $unify types$,
  423.                 FUNCTOR1,
  424.                 FUNCTOR2,
  425.                 NEW_TYPE ),
  426.       frame_op( $unify slots in frame1$,
  427.                 SLOTS1  ,
  428.                 SLOTS2  ,
  429.                 NEW_SLOTS1 ),
  430.       frame_op( $unify slots in frame2$,
  431.                 SLOTS1  ,
  432.                 SLOTS2  ,
  433.                 NEW_SLOTS2 ),
  434.       append(   NEW_SLOTS1  ,
  435.                 NEW_SLOTS2  ,
  436.                 NEW_SLOTS   ),
  437.       (      NEW_TYPE == untyped ,
  438.              !,
  439.              NEW_FRAME = NEW_SLOTS
  440.       ;
  441.              NEW_FRAME =..[ NEW_TYPE,  NEW_SLOTS ]
  442.       ),
  443.    frame_op( $x trace$,
  444.              $unify frames$,
  445.              NEW_FRAME   ) .
  446.  
  447. % cl 12
  448. frame_op( $unify types$,
  449.           untyped ,
  450.           FUNCTOR2,
  451.           FUNCTOR2 ) :- !,
  452.    frame_op( $x trace$,
  453.              $unify types$,
  454.              FUNCTOR2    ) .
  455.  
  456. % cl 13
  457. frame_op( $unify types$,
  458.           FUNCTOR1,
  459.           untyped ,
  460.           FUNCTOR1 ) :- !,
  461.    frame_op( $x trace$,
  462.              $unify types$,
  463.              FUNCTOR1    ) .
  464.  
  465. % cl 14
  466. frame_op( $unify types$,
  467.           FUNCTOR1,
  468.           FUNCTOR1,
  469.           FUNCTOR1 ) :- !,
  470.    frame_op( $x trace$,
  471.              $unify types$,
  472.              FUNCTOR1    ) .
  473.  
  474. % cl 15
  475. frame_op( $unify slots in frame1$,
  476.           SLOTS1  ,
  477.           _       ,
  478.           NEW_SLOTS1 ) :-
  479.       SLOTS1  = [] ,
  480.       !,
  481.       NEW_SLOTS1 = [] ,
  482.    frame_op( $x trace$,
  483.              $unify slots in frame1$,
  484.              NEW_SLOTS1  ) .
  485.  
  486. % cl 16
  487. frame_op( $unify slots in frame1$,
  488.           SLOTS1  ,
  489.           SLOTS2  ,
  490.           NEW_SLOTS1 ) :-
  491.       SLOTS1  = [ SLOT : VALUE1 | REST ],
  492.       frame_op( $get slot value with default$,
  493.                 SLOTS2  ,
  494.                 SLOT,
  495.                 VALUE1  ,
  496.                 VALUE2 ) ,
  497.       VALUE2 = VALUE1 ,
  498.       NEW_SLOTS1 = [ SLOT : VALUE1 | REST1 ],
  499.       frame_op( $unify slots in frame1$,
  500.                 REST    ,
  501.                 SLOTS2  ,
  502.                 REST1  ) ,
  503.    frame_op( $x trace$,
  504.              $unify slots in frame1$,
  505.              NEW_SLOTS1  ) .
  506.  
  507.  
  508. % cl 17
  509. frame_op( $unify slots in frame2$,
  510.           _   ,
  511.           SLOTS2  ,
  512.           NEW_SLOTS2 ) :-
  513.       SLOTS2  = [],
  514.       !,
  515.       NEW_SLOTS2 = [] ,
  516.    frame_op( $x trace$,
  517.              $unify slots in frame2$,
  518.              NEW_SLOTS2  ) .
  519.  
  520. % cl 18
  521. frame_op( $unify slots in frame2$,
  522.           SLOTS1  ,
  523.           SLOTS2  ,
  524.           NEW_SLOTS2 ) :-
  525.     SLOTS2  = [ SLOT : VALUE1 | REST ],
  526.     (      frame_op( $has slot$,
  527.                      SLOTS1  ,
  528.                      SLOT ),
  529.            !,
  530.            frame_op( $unify slots in frame2$,
  531.                      SLOTS1  ,
  532.                      REST    ,
  533.                      NEW_SLOTS2 )
  534.     ;
  535.            NEW_SLOTS2  = [ SLOT : VALUE1 | COMPUTED_REST ],
  536.            frame_op( $unify slots in frame2$,
  537.                      SLOTS1  ,
  538.                      REST    ,
  539.                      COMPUTED_REST  )
  540.     ),
  541.    frame_op( $x trace$,
  542.              $unify slots in frame2$,
  543.              NEW_SLOTS2  ) .
  544.  
  545.  
  546.  
  547. %%%%%%%%%%%%%%%%% frame_op / 5    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  548. %%%%%%%%%%%%%%%%% frame_op / 5    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  549.  
  550. :- mode frame_op( +,+,+,+,?).
  551.  
  552.  
  553. frame_op( KEY,
  554.           FRAME1 ,
  555.           FRAME1a ,
  556.           FRAME1b ,
  557.           FRAME2  ) :-
  558.      ARGS = [ FRAME1, FRAME1a , FRAME1b ,  FRAME2 ],
  559.      frame_op( $trace$,
  560.                KEY,
  561.                ARGS ) ,
  562.      fail.
  563.  
  564. frame_op( $get pair value$,
  565.           SOURCE_FRAME,
  566.           SLOT ,
  567.           PAIR ,
  568.           VALUE  ) :-
  569.     PAIR = _ : REST ,
  570.                /*-TRACE-*/         trace_message( frame_op   ,
  571.                /*-TRACE-*/                        $...REST = $,
  572.                /*-TRACE-*/                        REST  ),
  573.     (
  574.          var( REST ),
  575.          !,
  576.          frame_op( $get slot value$,
  577.                    SOURCE_FRAME,
  578.                    SLOT,
  579.                    VALUE )
  580.     ;
  581.                 % PAIR =  SLOT : unacceptable : BAD_VALUE ,
  582.          REST =   unacceptable : BAD_VALUE ,
  583.          !,
  584.          (
  585.                   frame_op( $get slot value$,
  586.                             SOURCE_FRAME,
  587.                             SLOT,
  588.                             VALUE ) ,
  589.                   !,
  590.                   not BAD_VALUE = VALUE
  591.          ;
  592.                   true
  593.          )
  594.     ;
  595.                 %   PAIR =  SLOT : optional : VALUE
  596.          REST =   optional : GOOD_VALUE ,
  597.          ! ,
  598.          (
  599.                   frame_op( $get slot value$,
  600.                             SOURCE_FRAME,
  601.                             SLOT,
  602.                             VALUE ) ,
  603.                   !,
  604.                   GOOD_VALUE = VALUE
  605.          ;
  606.                   true
  607.          )
  608.     ) ,
  609.    frame_op( $x trace$,
  610.              $get pair value$,
  611.              VALUE  ) .
  612.  
  613.  
  614. %%%%%%%%%%%%%%%%%%% learn indexed frame update  %%%%%%%%%%%%%%%%%%%
  615.  
  616. % cl 1
  617. frame_op( $learn indexed frame update$,
  618.           KEY  ,
  619.           OLD_FRAME ,
  620.           NEW_SLOTS ,
  621.           NEW_FRAME ) :-
  622.  
  623.       frame_op( $unify frames$,
  624.                 OLD_FRAME ,
  625.                 NEW_SLOTS ,
  626.                 NEW_FRAME ) ,
  627.       recorded( KEY, OLD_FRAME, REF ),
  628.       replace( REF, NEW_FRAME ),
  629.    frame_op( $x trace$,
  630.              $learn indexed frame update$,
  631.              NEW_FRAME   ) .
  632.  
  633. %%%%%%%%%%%%%%%%%%% get slot value with default %%%%%%%%%%%%%%%%%%%
  634.  
  635. % cl 2
  636. frame_op( $get slot value with default$,
  637.           FRAME,
  638.           SLOT,
  639.           _ , % DEFAULT,
  640.           VALUE ) :-
  641.       frame_op( $get slot value$,
  642.                 FRAME,
  643.                 SLOT,
  644.                 VALUE ) ,
  645.       !,
  646.    frame_op( $x trace$,
  647.              $get slot value with default$,
  648.              VALUE       ) .
  649.  
  650. % cl 3
  651. frame_op( $get slot value with default$,
  652.           _    ,
  653.           _   ,
  654.           DEFAULT,
  655.           DEFAULT ) :- !,
  656.    frame_op( $x trace$,
  657.              $get slot value with default$,
  658.              DEFAULT     ) .
  659.  
  660. %%%%%%%%%%%%%%%%% frame_op / 6    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  661. %%%%%%%%%%%%%%%%% frame_op / 6    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  662.  
  663. :- mode frame_op( +,+,+,+,+,?).
  664.  
  665.  
  666. frame_op( KEY,
  667.           FRAME1 ,
  668.           FRAME1a ,
  669.           FRAME1b ,
  670.           FRAME1C ,
  671.           FRAME2  ) :-
  672.      ARGS = [ FRAME1, FRAME1a , FRAME1b ,   FRAME1C ,  FRAME2 ],
  673.      frame_op( $trace$,
  674.                KEY,
  675.                ARGS ) ,
  676.      fail.
  677.  
  678. frame_op( $learn indexed and Prolog database frame update$,
  679.           KEY      ,
  680.           PATTERN ,
  681.           OLD_OBJECT  ,
  682.           SLOTS ,
  683.           NEW_STATEMENT_OBJECT )   :-
  684.       frame_op( $learn indexed frame update$,
  685.                 KEY      ,
  686.                 OLD_OBJECT  ,
  687.                 SLOTS ,
  688.                 NEW_STATEMENT_OBJECT ),
  689.        frame_op( $learn prolog database frame update$,
  690.                  PATTERN,
  691.                  NEW_STATEMENT_OBJECT ) .
  692. %%%%%%%%%%%%%%%%%%%%%%%%%% eof %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  693.